package com.cpms.framework.redis.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cpms.framework.common.enums.GlobalResponseResultEnum;
import com.cpms.framework.common.exception.BizException;
import com.cpms.framework.common.utils.CsMd5Util;
import io.jsonwebtoken.lang.Objects;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description: 锁切面工具类
 * @author: gulang
 * @time: 2021/11/29 16:07
 */
public class CsLockAspectUtil {
    /**
     *  获取锁指定的字段对应的参数值
     * @param point
     * @param fields 锁指定的字段名称
     * @return
     */
    public static Map<String, Object> getParams(JoinPoint point, String[] fields){
        Map<String, Object> param =  new HashMap<>();
        Object[] reqArgs = point.getArgs();
        List<String> targetFields = Arrays.asList(fields);
        if(Objects.isEmpty(reqArgs)) {
            throw new BizException(GlobalResponseResultEnum.REPEAT_SUBMIT_PARAM_EMPTY_ERROR);
        }
        for (int i = 0; i < reqArgs.length; i++) {
            try {
                JSONObject paramJson = JSON.parseObject(JSON.toJSONString(reqArgs[i]));
                //得到属性
                for (int j = 0; j < targetFields.size(); j++) {
                    if (paramJson.get(targetFields.get(j)) != null) {
                        param.put(targetFields.get(j), paramJson.get(targetFields.get(j)));
                    }
                }
            }catch (Exception e) {
                String defaultField = "default_filed";
                param.putIfAbsent(defaultField,reqArgs[0]);
            }
        }
        if (param.size() > 0) {
            return param;
        }
        throw new BizException(GlobalResponseResultEnum.REPEAT_SUBMIT_PARAM_EMPTY_ERROR);
    }

    /**
     *  创建lock key
     * @param prefixKey lock前缀
     * @param value 指定的动态字段参数值
     * @param point
     * @return
     */
    public static String createLockKey( String prefixKey,Object value, ProceedingJoinPoint point)  {
        Signature signature = point.getSignature();
        Method method = ((MethodSignature) signature).getMethod();
        return prefixKey +method.getDeclaringClass().getSimpleName()+":"+ method.getName() + ":" + CsMd5Util.md5Encrypt(value.toString());
    }
}
